package cz.semjob.learning.instances;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cz.semjob.common.attribute.value.AttributeValue;
import cz.semjob.common.attribute.value.DoubleAttributeValue;
import cz.semjob.common.attribute.value.StringAttributeValue;
import cz.semjob.document.processing.DocumentInstance;
import cz.semjob.document.processing.DocumentWord;
import cz.semjob.learning.data.TaxonomyLearningException;
import cz.semjob.learning.data.attribute.AInstanceAttribute;

public class UnlabeledTextInstance implements ITextInstance {

	protected final List<AInstanceAttribute> attributesList;

	protected String text;

	protected List<DocumentWord> words;

	protected final Map<String, AttributeValue> attributeValues;

	protected DocumentInstance documentInstance;

	public UnlabeledTextInstance(List<AInstanceAttribute> attributesList,
			DocumentInstance documentInstance) {
		super();
		attributeValues = new HashMap<String, AttributeValue>();
		this.attributesList = attributesList;
		this.documentInstance = documentInstance;
	}

	public String getText() {
		if (text == null && words != null) {
			String text = "\"";
			for (DocumentWord word : words) {
				text = text + word.getText() + " ";
			}
			text += "\"";
			this.text = text;
		}
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public List<DocumentWord> getWords() {
		return words;
	}

	public void setWords(List<DocumentWord> words) {
		this.words = words;
	}

	public Map<String, AttributeValue> getAttributeValues() {
		return attributeValues;
	}

	public void addAttributeValue(String attributeName, Object attributeValue)
			throws TaxonomyLearningException {
		AttributeValue convertedValue = null;
		if (attributeValue instanceof Integer) {
			convertedValue = new DoubleAttributeValue(attributeName,
					((Integer) attributeValue).doubleValue());
			this.attributeValues.put(attributeName, convertedValue);
		} else if (attributeValue instanceof String) {
			convertedValue = new StringAttributeValue(attributeName,
					(String) attributeValue);
			this.attributeValues.put(attributeName, convertedValue);
		} else if (attributeValue instanceof Double) {
			convertedValue = new DoubleAttributeValue(attributeName,
					(Double) attributeValue);
			this.attributeValues.put(attributeName, convertedValue);
		} else if (attributeValue instanceof AttributeValue) {
			this.attributeValues.put(attributeName,
					(AttributeValue) attributeValue);
		} else {
			throw new TaxonomyLearningException("Unknow attribute value: "
					+ attributeValue);
		}
	}

	@Override
	public String toString() {
		return "UnlabeledTextInstance [text=" + getText() + ", words=" + words
				+ ", attributeValues=" + attributeValues + "]\n";
	}

	public List<AInstanceAttribute> getAttributesList() {
		return attributesList;
	}

	public DocumentInstance getDocumentInstance() {
		return documentInstance;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((attributeValues == null) ? 0 : attributeValues.hashCode());
		result = prime * result
				+ ((attributesList == null) ? 0 : attributesList.hashCode());
		result = prime
				* result
				+ ((documentInstance == null) ? 0 : documentInstance.hashCode());
		result = prime * result + ((text == null) ? 0 : text.hashCode());
		result = prime * result + ((words == null) ? 0 : words.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		UnlabeledTextInstance other = (UnlabeledTextInstance) obj;
		if (attributeValues == null) {
			if (other.attributeValues != null)
				return false;
		} else if (!attributeValues.equals(other.attributeValues))
			return false;
		if (attributesList == null) {
			if (other.attributesList != null)
				return false;
		} else if (!attributesList.equals(other.attributesList))
			return false;
		if (documentInstance == null) {
			if (other.documentInstance != null)
				return false;
		} else if (!documentInstance.equals(other.documentInstance))
			return false;
		if (text == null) {
			if (other.text != null)
				return false;
		} else if (!text.equals(other.text))
			return false;
		if (words == null) {
			if (other.words != null)
				return false;
		} else if (!words.equals(other.words))
			return false;
		return true;
	}

}
